﻿using System;
using System.Reflection;
using GojiSoft.EventSequenceUnitTesting.ExampleSupport;
using GojiSoft.EventSequenceUnitTesting.Tests.Support;

namespace GojiSoft.EventSequenceUnitTesting {
    class Program {
        private const int EventTimeoutMS = 1000;

        static void Main() {
            Console.WriteLine("**Example of event sequence testing**");
            EventTest1();

            Console.WriteLine("\n**Example of event sequence testing - INotifyPropertyChanged**");
            EventTest2();

            Console.WriteLine("\n**Example of dynamic event subscription**");
            EventSubscription();

            Console.ReadKey(true);
        }

        static void EventTest1() {
            AsyncEventPublisher publisher = new AsyncEventPublisher();

            Action test = () => {
                publisher.ChangeA();
                publisher.ChangeC();
                publisher.ChangeB();
            };

            string[] expectedSequence = new[] { "EventA", "EventB", "EventC" };

            try {
                EventMonitor.Assert(test, publisher, expectedSequence, EventTimeoutMS);
            } catch(EventMonitoringException ex) {
                Console.WriteLine(ex.Message);
            }
        }

        static void EventTest2() {
            NotifyPropertyChangedEventPublisher publisher = new NotifyPropertyChangedEventPublisher();

            Action test = () => {
                publisher.Y = 2;
                publisher.X = 1;
            };

            string[] expectedSequence = new[] { "X", "Y" };

            try {
                EventMonitor.Assert(test, publisher, expectedSequence);
            } catch(EventMonitoringException ex) {
                Console.WriteLine(ex.Message);
            }
        }

        static void EventSubscription() {
            AsyncEventPublisher publisher = new AsyncEventPublisher();

            foreach(EventInfo eventInfo in publisher.GetType().GetEvents()) {
                DynamicEvent.Subscribe(eventInfo, publisher, (sender, e, eventName) => {
                    Console.WriteLine("Event raised: " + eventName);

                    ReflectionUtils.PrintProperties(e);
                });
            }

            publisher.ChangeA();
            publisher.ChangeB();
            publisher.ChangeC();
        }
    }
}